﻿<!DOCTYPE html>
<html>
<head>
<title>呼叫中心html客户端工具条</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link rel="stylesheet" href="page.css" />
    <script type="text/javascript" src="jquery-1.11.0.js"></script>
    <script type="text/javascript" src="ccPhoneBarSocket.js"></script>
	  
    <script type="text/javascript">
        var _phoneBar = new ccPhoneBarSocket();
        var scriptServer = "127.0.0.1";
        var  extnum = '1001'; //分机号
        var opnum = '1001'; //工号
        var skillLevel = 9; //技能等级
        var groupId = 1; // 业务组id
        if(window.location.href.toString().indexOf("?") != -1){
            console.log( ccPhoneBarSocket.utils );
            extnum = ccPhoneBarSocket.utils.getQueryParam("extNum");
            opnum = ccPhoneBarSocket.utils.getQueryParam("opNum");
            groupId = ccPhoneBarSocket.utils.getQueryParam("groupId");
            console.log("extNum=", extnum, "opNum=", opnum);
        }

        function resetExtNumAndOpNum(ext, op, groupId) {
            window.location.href = "?extNum=" + ext + "&opNum=" + op + "&groupId=" + groupId;
        };

		(function loadLoginToken(){

            // 目前已经把 projectId 和 groupId合并为同一个参数;
            var getTokenUrl = "http://"+ scriptServer +":8880/call-center/create-token";
            var destUrl = getTokenUrl + "?extnum=" + extnum + "&opnum=" + opnum
            + "&groupId=" + groupId +"&skillLevel=" + skillLevel
            ;

            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = destUrl;
            document.getElementsByTagName('head')[0].appendChild(script);
		})();

        (function loadExtPassword(){
            var  extPassword = '1234567';
            var url = "http://"+ scriptServer +":8880/call-center/create-ext-password?pass=" + extPassword;
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = url;
            document.getElementsByTagName('head')[0].appendChild(script);
        })();

        (function loadGatewayList(){
            var url = "http://"+ scriptServer +":8880/call-center/create-gateway-list" ;
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = url;
            document.getElementsByTagName('head')[0].appendChild(script);
        })();

        // 将视频级别填充到下拉列表中的函数
        function populateVideoLevelDropdown(objId) {
            let select = document.getElementById(objId);
            if(select == null) return;
            // 遍历视频级别数据
            for (let key in ccPhoneBarSocket.videoLevels) {
                if (ccPhoneBarSocket.videoLevels.hasOwnProperty(key)) {
                    let level = ccPhoneBarSocket.videoLevels[key];
                    let option = document.createElement('option');
                    option.value = level.levelId; // 设置值为 levelId
                    option.text = level.description; // 显示文本
                    select.appendChild(option);
                }
            }
            select.value = ccPhoneBarSocket.videoLevels.HD.levelId ;
        }

	</script>

<script> 
var _callConfig = null;

window.onload = function(){

    // 调用函数填充视频清晰度的下拉列表
    populateVideoLevelDropdown('videoLevelSelect');
    populateVideoLevelDropdown('member_video_level');

	//工具条对象断开事件
	// _phoneBar.on(ccPhoneBarSocket.eventList.ws_disconnected, function(msg){
	// 	console.log(msg);
	// });
    //
    // //工具条对象连接成功
    // _phoneBar.on(ccPhoneBarSocket.eventList.ws_connected, function(msg){
    //     console.log(msg);
    // });
    //
	// _phoneBar.on(ccPhoneBarSocket.eventList.callee_ringing, function(msg){
	// 	console.log(msg.content, "被叫振铃事件");
	// });
	// _phoneBar.on(ccPhoneBarSocket.eventList.caller_answered, function(msg){
	// 	console.log(msg, "主叫接通" );
	// });
    // _phoneBar.on(ccPhoneBarSocket.eventList.caller_hangup, function(msg){
    //     console.log(msg, "主叫挂断");
    // });
    //
	// _phoneBar.on(ccPhoneBarSocket.eventList.callee_answered, function(msg){
	// 	console.log(msg, "被叫接通");
	// });
	// _phoneBar.on(ccPhoneBarSocket.eventList.callee_hangup, function(msg){
	// 	console.log(msg, "被叫挂断");
	// });
    //
	// _phoneBar.on(ccPhoneBarSocket.eventList.status_changed, function(msg){
	// 	console.log("座席状态改变: " ,msg);
	// });
    //
    // // 一次外呼结束;
    // _phoneBar.on(ccPhoneBarSocket.eventList.outbound_finished, function(msg){
    // 	console.log('一次外呼结束', msg);
    // });

    // websocket通信对象断开事件;
    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.ws_disconnected.code, function(msg){
        console.log(msg);
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.ws_disconnected.code);
        $("#transfer_area").hide();
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.OUTBOUND_START, function (msg) {
        console.log('outbound_start',msg);
    });

    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.request_args_error.code, function(msg){
        console.log(msg);
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.request_args_error.code);
    });

    //用户已在其他设备登录
    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.code, function(msg){
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.code);
        alert(ccPhoneBarSocket.eventListWithTextInfo.user_login_on_other_device.msg);
    });

    //websocket连接成功
    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.ws_connected.code, function(msg){
        console.log(msg);
        $("#loginTime").text(new Date().toLocaleTimeString());
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.ws_connected.code);
    });

    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.callee_ringing.code, function(msg){
        console.log(msg.content, "被叫振铃事件");
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.callee_ringing.code);
    });
    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.caller_answered.code, function(msg){
        console.log(msg, "主叫接通" );
        $("#agentStatus").text("通话中");
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.caller_answered.code);
    });
    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.caller_hangup.code, function(msg){
        console.log(msg, "主叫挂断");
        $("#agentStatus").text("通话结束");
        $("#reInviteVideoBtn").attr("disabled","disabled");
        $("#sendVideoFileBtn").attr("disabled","disabled");
        $("#transfer_area").hide();
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.caller_hangup.code);
    });

    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.callee_answered.code, function(msg){
        console.log(msg, "被叫接通");
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.callee_answered.code);
    });
    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.callee_hangup.code, function(msg){
        console.log(msg, "被叫挂断");
        $("#transfer_area").hide();
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.callee_hangup.code);
    });

    _phoneBar.on(ccPhoneBarSocket.eventListWithTextInfo.status_changed.code, function(msg){
        console.log("座席状态改变: " ,msg);
        $("#agentStatus").text(msg["object"]["text"]);
        _phoneBar.updatePhoneBar(msg, ccPhoneBarSocket.eventListWithTextInfo.status_changed.code);
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.acd_group_queue_number, function(msg){
        console.log("当前排队人数消息: " ,msg);
        $("#queueStat").text(msg["object"]["queue_number"]);
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.on_audio_call_connected, function(msg){
        console.log("音频通话已建立: " ,msg);
        $("#reInviteVideoBtn").removeAttr("disabled");
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.customer_channel_hold, function (msg) {
        console.log("客户通话已保持: " ,msg);
        $("#callStatus").text("通话已保持");
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.customer_channel_unhold, function (msg) {
        console.log("客户通话已接回." ,msg);
        $("#callStatus").text("客户通话已接回");
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.on_video_call_connected, function(msg){
        console.log("视频通话已建立: " ,msg);
        $("#sendVideoFileBtn").removeAttr("disabled");
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.inner_consultation_start, function(msg){
        $("#callStatus").text("咨询开始.");
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.inner_consultation_stop, function(msg){
        $("#callStatus").text("咨询结束.");
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.transfer_call_success, function(msg){
        $("#callStatus").text("电话转接成功.");
        $("#externalPhoneNumber").val('');
    });

    // 订阅的坐席状态列表发生改变
    _phoneBar.on(ccPhoneBarSocket.eventList.agent_status_data_changed, function (msg) {
        console.log("agent_status_data_changed.");
        // 当 transfer_to_groupId 值改变时更新 transfer_to_member
        $(transferToGroupId).off("change");
        $(transferToGroupId).on("change", function () {
            refreshMemberIdList();
        });
        refreshMemberIdList();
    });

    /* conference related events  */
    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_ANSWERED, function (msg) {
        console.log("会议成员已经接通.", msg);
        var memberPhone = $.trim(msg.object.phone);
        var memberItemId = "#conf_member_" + memberPhone;

        $(".conf_status", $(memberItemId)).text(msg.object.status);
        $(".conf_status", $(memberItemId)).html("通话中").css("color", "green");

        $(".conf_mute", $(memberItemId)).find("img").show();
        $(".conf_vmute", $(memberItemId)).find("img").show();
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_VMUTED_SUCCESS, function (msg) {
        console.log("会议成员已被禁用视频.", msg);
        var memberPhone = $.trim(msg.object.phone);
        var muteObj = $(".conf_vmute", $("#conf_member_" + memberPhone));
        muteObj.find("img")[0].src = "images/no_video.jpg";
        muteObj.find("a").removeAttr("onclick");
        muteObj.find("a").off("click");
        muteObj.find("a").on("click", function () {
            _phoneBar.conferenceUnVMuteMember(memberPhone);
        } );
    });
    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_UnVMUTED_SUCCESS, function (msg) {
        console.log("会议成员启用视频成功.", msg);
        var memberPhone = $.trim(msg.object.phone);
        var muteObj = $(".conf_vmute", $("#conf_member_" + memberPhone));
        muteObj.find("img")[0].src = "images/video.jpg";
        muteObj.find("a").removeAttr("onclick");
        muteObj.find("a").off("click");
        muteObj.find("a").on("click", function () {
            _phoneBar.conferenceVMuteMember(memberPhone);
        } );
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_MUTED_SUCCESS, function (msg) {
        console.log("会议成员已被禁言.", msg);
        var memberPhone = $.trim(msg.object.phone);
        var muteObj = $(".conf_mute", $("#conf_member_" + memberPhone));
        muteObj.find("img")[0].src = "images/unmute.jpg";
        muteObj.find("a").removeAttr("onclick");
        muteObj.find("a").off("click");
        muteObj.find("a").on("click", function () {
            _phoneBar.conferenceUnMuteMember(memberPhone);
        } );
    });
    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_UNMUTED_SUCCESS, function (msg) {
        console.log("会议成员解除禁言成功.", msg);
        var memberPhone = $.trim(msg.object.phone);
        var muteObj = $(".conf_mute", $("#conf_member_" + memberPhone));
        muteObj.find("img")[0].src = "images/mute.jpg";
        muteObj.find("a").removeAttr("onclick");
        muteObj.find("a").off("click");
        muteObj.find("a").on("click", function () {
            _phoneBar.conferenceMuteMember(memberPhone);
        } );
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MEMBER_HANGUP, function (msg) {
        console.log("会议成员已经挂机.", msg);
        var memberPhone = $.trim(msg.object.phone);
        var memberItemId = "#conf_member_" + memberPhone;

        // 隐藏 mute及 vmute按钮
        $(".conf_mute", $(memberItemId)).find("img").hide();
        $(".conf_vmute", $(memberItemId)).find("img").hide();
        $(".conf_re_invite", $(memberItemId)).show();

        var answerStatus = ( msg.object.answeredTime === 0) ? "未接通" :  msg.object.hangupClause;
        var color = ( msg.object.answeredTime === 0) ? "red" : "green";
        $(".conf_status", $(memberItemId)).html("已挂机("+ answerStatus  +")").css("color", color);
        $(".conf_status", $(memberItemId)).fadeTo('fast', 0.1).fadeTo('fast', 1.0);
        var blinkText = setInterval(function () {
            $(".conf_status", $(memberItemId)).fadeTo('fast', 0.1).fadeTo('fast', 1.0);
        }, 700); // 每0.5秒闪烁一次

        setTimeout(function () {
            console.log("memberItemId=", memberItemId);
            clearInterval(blinkText);
            // $(memberItemId).remove(); //暂不自动移除参会者，由主持人手动操作处理;
        }, 5000);
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MODERATOR_ANSWERED, function (msg) {
        console.log("电话会议开始，主持人已接通.", msg);
        onConferenceStart();
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_MODERATOR_HANGUP, function (msg) {
        console.log("电话会议结束，主持人已挂机.", msg);
        onConferenceEnd();
    });

    _phoneBar.on(ccPhoneBarSocket.eventList.CONFERENCE_TRANSFER_SUCCESS_FROM_EXISTED_CALL, function (msg) {
        console.log("成功把通话转接到多人视频会议.", msg);
        onTransferToConferenceSuccess(msg);
    });


    // 电话工具条参数配置;
	_callConfig = {
        'useDefaultUi' : true,
        // loginToken 信息是加密的字符串， 包含以下字段信息：extnum[分机号]、opnum[工号]、groupId[业务组]、skillLevel[技能等级]
        'loginToken': '',

         // 电话工具条服务器端的地址; 端口默认是1081
        'ipccServer': scriptServer + ':1081',

        // 网关列表， 默认需要加密后在在通过客户端向呼叫系统传递;
        // 注意在注册模式下，网关参数更改之后，必须重启语音服务 [docker restart freeswitch] 方可生效，不支持热更新;
        // 支持多个网关同时使用，按照优先级依次使用, 支持网关负载容错溢出 [第一条网关外呼出错后，自动使用第二条网关重试，直至外呼不出错] ;
        'gatewayList': [
            {
                uuid: '01',   // 网关唯一编号;
                updateTime: 1992622572983,  //网关信息更新时间, 每次修改必须更新这个字段，否则配置无法生效;
                gatewayAddr: '192.168.67.219',  // 网关地址或名称，  如果是注册模式： 网关地址参数则填写为网关名称;
                callerNumber: '007',                 //主叫号码
                calleePrefix: '',                    // 被叫前缀
                priority: 2,                         //优先级，数字越小，越优先被使用;
                concurrency: 20,                    // 网关并发数，同时支持呼叫数;
                register: false,                     // 是否为注册模式
                audioCodec: 'g711'                   // 网关通信语音编码;
            }  
        ],

        // 网关列表信息是否为加密模式;
        'gatewayEncrypted': false
    };

    // 使用工具条之前需要先初始化 _callConfig 参数， 填充各个字段的值： 合计7个字段，必须填写正确 ；
	//********************************************************************************************
    // 以下代码设置加密的参数： loginToken、extPassword、gatewayList；   在本页面的demo演示中需要调用服务器端接口获取密文字符串;

	console.log('loginToken = ',loginToken);
	if(typeof(loginToken) != "undefined") {
        _callConfig["loginToken"] = loginToken;
    } else{
	    alert("电话工具条：无法获取 loginToken!");
	    return;
    }

    console.log('_phoneEncryptPassword = ',_phoneEncryptPassword);
    if(typeof(_phoneEncryptPassword) != "undefined") {
        _callConfig["extPassword"] = _phoneEncryptPassword;
    } else{
        alert("电话工具条：无法获取 _phoneEncryptPassword!");
        return;
    }

    console.log('_configGatewayList = ', _configGatewayList);
    if(typeof(_configGatewayList) != "undefined" && _callConfig["gatewayEncrypted"]) {
        //_callConfig["gatewayList"] = _configGatewayList;
    } else{
       //  alert("电话工具条：无法获取 _configGatewayList!");
    }

    _phoneBar.initConfig(_callConfig);
};

function onConferenceEnd() {
    document.getElementById("endConference").setAttribute("disabled", "true");
    document.getElementById("startConference").removeAttribute("disabled");
    document.getElementById("conference_member_list").style.display = "none";
    // 启用外呼按钮
    $("#callBtn").addClass('on');
    // 启用置闲按钮
    $("#setFree").addClass('on');
    // 启用签出按钮
    $("#onLineBtn").addClass('on');
    //移除所有的参会成员
    $(".conf_member_item_row").remove();

    let tips = "多方通话结束";
    $("#callStatus").text(tips);
    $("#agentStatus").text(tips);
}

function onConferenceStart() {
    document.getElementById("endConference").removeAttribute("disabled");
    document.getElementById("conference_member_list").style.display = "block";
    let tips = "多方通话进行中";
    $("#callStatus").text(tips);
    $("#agentStatus").text(tips);
}

/**
 *  成功把电话转接到多人视频会议
 */
function onTransferToConferenceSuccess(msg) {
    $("#callStatus").text("已接入多方会议");
    $("#setFree").removeClass("on");
    $("#setBusy").removeClass("on");
    $("#callBtn").removeClass("on");

    //界面显示成功转接到视频会议电话
    var phone = msg.object.phone;
    var name = msg.object.phone;
    console.log("onTransferToConferenceSuccess:", msg);
    _phoneBar.conferenceAddMemberFromExistCall(name, phone);
}


</script>

</head>
<body>

<form>

<table width="1224">
<tr>
  <td width="70%" colspan="2" height="35" style="text-indent: 20px;">
      <b>签入时间：</b> <span id="loginTime" title="" class="status4">00:00:00</span> &nbsp;&nbsp;
      <b>状态：</b> <span id="agentStatus" title="" class="status4">空闲</span> &nbsp;&nbsp;
      <b>当前排队人数：</b><span id="queueStat" title="" class="status4">0</span>

  </td>
</tr>
<tr>
<td width="70%">
<div>
    <div class="head_dial" style="padding-left: 10px; ">
	     
        <dl class="dial">
            <dt>
                <label for="ccphoneNumber"></label><input type="text" name="ccphoneNumber" id="ccphoneNumber" placeholder="输入电话号码" class="tel_txt" />
            </dt>
            <dd>
                <ul><li id="callStatus" title="" class="status4">没有连接</li></ul>
                <span id="showCallLen" style="display:none"><b>00:00</b></span>
            </dd>
        </dl>

        <ul class="dial_btn">
            <li><a href="#" id="setFree" class="xz_btn off"></a><span>置闲</span></li>
            <li><a href="#" id="setBusy" class="sm_btn off"></a>
                <select style="width: 50px;" id="setBusySubList">
                    <option value="3">置忙</option>
                    <option value="31">小休</option>
                    <option value="32">会议</option>
                    <option value="33">培训</option>
                </select>
            </li>
            <li><a href="#" id="callBtn" class="wh_btn"></a><span>外呼</span></li>
            <li id="holdBtnLi"><a href="#" id="holdBtn" class="bc_btn off"></a><span>保 持</span></li>
            <li id="unHoldBtnLi"><a href="#" id="unHoldBtn" class="bc2_btn off"></a><span>取消保持</span></li>
            <li><a href="#" id="transferBtn" class="zjie_btn"></a><span>转接</span></li>
            <li><a href="#" id="consultationBtn" class="zixun_btn"></a><span>咨询</span></li>
            <li><a href="#" id="conferenceBtn" class="hy_btn"></a><span>会议</span></li>
            <li><a href="#" id="hangUpBtn" class="gj_btn"></a><span>挂机</span></li>
            <li><a href="#" id="resetStatus" class="qz_btn"></a><span>强置</span></li>
            <li><a href="#" id="onLineBtn" class="sx_btn on"></a><span>签入</span></li>
        </ul>
    </div>
</div>
</td>
<td width="30%" style="display: none;">
<div>
    <div  style="padding-left: 10px; ">
        &nbsp; &nbsp;  外呼设置：
        <label for="videoCallBtn"> <input type="radio" value="video" name="callType" id="videoCallBtn" />视频外呼</label>  &nbsp;&nbsp;
        <label for="audioCallBtn"> <input type="radio" value="audio"  name="callType" checked="checked" id="audioCallBtn"  />语音外呼</label>  <br />

        &nbsp; &nbsp; 视频清晰度:
        <label for="videoLevelSelect"></label><select id="videoLevelSelect">
        </select>
        <input type="button" id="reInviteVideoBtn" title="发送视频邀请，可把音频通话转换为视频通话。"
         onclick="_phoneBar.reInviteVideoCall();"       value="视频邀请" disabled="disabled" >

        &nbsp;&nbsp;&nbsp;&nbsp;
        <label for="videoListSelect"></label>
         <select id="videoListSelect">
             <option value="">请选择视频</option>
             <option value="/usr/local/freeswitchvideo/share/freeswitch/sounds/bank.mp4">客服实例视频</option>
             <option value="/usr/local/freeswitchvideo/share/freeswitch/sounds/conference.mp4">多方会议视频</option>
             <option value="/usr/local/freeswitchvideo/share/freeswitch/sounds/15-seconds.mp4">15-seconds-demo</option>

         </select>
        <input type="button" id="sendVideoFileBtn" title="推送视频给对方，以便结束当前通话。"
               onclick="_phoneBar.sendVideoFile($('#videoListSelect').val());"   value="推送视频" disabled="disabled" >

    </div>
</div>
</td>
</tr>

    <tr id="conference_area" style="display: none">

        <td colspan="2" style="padding-left: 130px; padding-top: 30px;">
            <div>
                <div>
                    <div id="conference_start" style="display: block">
                        <!-- 会议布局: &nbsp; -->
                        <select id="conf_layout" name="conf_layout" style="display: none">
                            <option value="2x2">2x2</option>
                            <option value="3x3">3x3</option>
                            <option value="1up_top_left+3">一主三从</option>
                        </select>
                        &nbsp;
                        <!-- 画布尺寸: -->
                        <select id="conf_template" name="conf_template" style="display: none">
                            <option value="480p" selected="selected">480x640</option>
                            <option value="720p">720x1080</option>
                            <option value="default">default</option>
                        </select>
                        &nbsp;
                         会议类型:
                        <select id="conf_call_type2" name="conf_call_type2"  >
                           <!-- <option value="video">视频</option> -->
                            <option value="audio">音频</option>
                        </select>
                        <input type="hidden" value="audio" id="conf_call_type" name="conf_call_type" />
                        &nbsp;
                        <input type="button" name="startConference" id="startConference"
                               onclick="_phoneBar.conferenceStartBtnUI('')"
                               style="width: 70px;" value="启动会议">
                        &nbsp;
                        <input type="button" name="endConference" id="endConference"
                               onclick="_phoneBar.conferenceEnd()"
                               disabled="disabled"
                               style="width: 70px;" value="结束会议">
                    </div>

                    <div style="width: 100%;"> &nbsp; </div>

                    <div id="conference_member_list" style="display: none">
                        <ul>
                            <li id="conference_header">
                                <span class="conf_name"> <input id="member_name" name="member_name" placeholder="姓名" style="width: 60px;" /> </span> &nbsp;
                                <span class="conf_phone"> <input id="member_phone" name="member_phone" placeholder="手机号" style="width: 110px;" /> </span> &nbsp;
                                <span class="conf_call_type">
                                <select id="member_call_type" name="member_call_type" style="display: none">
                                   <option value="video">视频</option>
                                   <option value="audio" selected>音频</option>
                               </select>
                            </span>
                                <span class="conf_video_level" style="display: none">
                                <select id="member_video_level" name="member_video_level">
                               </select>
                            </span>

                                <span class="conf_name">
                               <input type="button" name="addConfMember" id="addConfMember"
                                      onclick="_phoneBar.conferenceAddMemberBtnUI(0)"
                                      style="width: 70px;" value="加入会议">
                           </span>
                            </li>

                            <!-- 会议成员展示模版html  -->
                            <li id="conf_member_template"  style="display: none;">
                                <span class="conf_name">{member_name}</span>
                                <span class="conf_phone">{member_phone}</span>
                                <span class="conf_mute"><a href="javascript:void(0)" onclick="_phoneBar.conferenceMuteMember('{member_phone}')"><img alt="禁言该成员。" src="images/mute.jpg" width="15" height="17" /> </a> </span>
                                <span class="conf_vmute" style="display: none"><a href="javascript:void(0)" onclick="_phoneBar.conferenceVMuteMember('{member_phone}')"><img alt="关闭该成员的视频。" src="images/video.jpg" /> </a></span>
                                <span class="conf_remove"><a href="javascript:void(0)" onclick="_phoneBar.conferenceRemoveMembers('{member_phone}')" title="踢除会议成员。">移除</a></span>
                                <span class="conf_re_invite"><a href="javascript:void(0)" onclick="_phoneBar.conferenceAddMemberBtnUI(1, '{member_phone}', '{member_name}')" title="重新呼叫。">重呼</a></span>
                                <span class="conf_status">{member_status}</span>
                            </li>


                            <li></li>
                        </ul>
                    </div>


                </div>
            </div>
        </td>

    </tr>

<tr id="transfer_area" width="100%" style="display: none">

        <td colspan="2" width="100%" style="padding-left: 140px; padding-top: 30px;">
            <table width="100%">
                 <tr>
                       <td width="90">业务组   </td>
                       <td width="90">坐席成员</td>
                       <td>&nbsp; </td>
                 </tr>
                <tr>
                    <td>
                        <select size="10" id="transfer_to_groupIds" name="transfer_to_groupIds">
                            <option value="">请选择</option>
                        </select>
                    </td>

                    <td>
                        <select size="10" id="transfer_to_member" name="transfer_to_member">
                            <option value="">请选择</option>
                        </select>
                    </td>
                    <td valign="middle">


                        &nbsp;&nbsp; <input type="text" name="externalPhoneNumber" id="externalPhoneNumber" placeholder="电话号码"
                               title="可以把当前通话转接到外线号码上。 如果该文本框留空，则忽略处理。"
                               class="tel_txt" />
                        <br /> <br />

                        &nbsp;&nbsp; <input type="button" name="doTransferBtn" id="doTransferBtn"
                               onclick="_phoneBar.transferBtnClickUI()"
                               style="width: 70px;" value="转接电话" title="把当前电话转接给他/她处理。" /> &nbsp;

                        &nbsp;&nbsp; <input type="button" name="stopCallWait" id="stopCallWait"
                               onclick="_phoneBar.stopCallWaitBtnClickUI()"
                               style="width: 70px;" value="接回客户" title="在咨询失败的情况下使用该按钮，接回处于等待中的电话。" /> &nbsp;

                        &nbsp;&nbsp; <input type="button" name="transferCallWait" id="transferCallWait"
                               onclick="_phoneBar.transferCallWaitBtnClickUI()"
                               style="width: 70px;" value="转接客户" title="在咨询成功的情况下使用该按钮，把电话转接给专家坐席。" /> &nbsp;

                       <input type="button" name="doConsultationBtn" id="doConsultationBtn"
                               onclick="_phoneBar.consultationBtnClickUI()"
                               style="width: 70px;" value="拨号咨询" title="" />

                    </td>
                </tr>
            </table>
        </td>

</tr>

</table>
</form>

<div id="chat-container">
    <div id="chat-messages" class="message-container"></div>
</div>

<script>
    // 以下是通话转接操作界面的功能
    const transferToGroupId = document.getElementById("transfer_to_groupIds");
    const transferToMember = document.getElementById("transfer_to_member");

    // 填充 transfer_to_groupId 数据
    function populateGroupIdOptions() {
        transferToGroupId.length = 0; //清除所有选项
        let groups = _phoneBar.callConfig.groups;
        groups.forEach(group => {
            const option = document.createElement("option");
            option.value = group.groupId;
            option.textContent = group.bizGroupName;
            transferToGroupId.appendChild(option);
        });
        if(transferToGroupId.selectedIndex == -1){
            transferToGroupId.selectedIndex = 0;
        }
    };

    // 根据选中的 groupId 填充 transfer_to_member 数据
    function populateMemberIdOptions(members, selectedGroupId) {
        if (!Array.isArray(members)) {
            console.error("populateMemberOptions: members is not a Array.", members);
            return;
        }
        transferToMember.innerHTML = '<option value="">请选择</option>';
        members
            .filter(member => member.groupId === selectedGroupId)
       .forEach(member => {
            const option = document.createElement("option");
        const statusMap = { 1 : "刚签入", 2: "空闲", 3: "忙碌", 4: "通话中", 5: "事后处理" };
        option.value = member.opnum;
        option.textContent = `${member.opnum}(${statusMap[member.agentStatus] || ""})`;
        transferToMember.appendChild(option);
      });
    };

    function refreshMemberIdList() {
        const selectedGroupId = transferToGroupId.value;
        if(selectedGroupId != "") {
            let origValue = transferToMember.value;
            populateMemberIdOptions(_phoneBar.callConfig.agentList, selectedGroupId);
            //判断原始选择项是否还存在，存在则重新赋值;
            let hasValue = transferToMember.querySelector(`option[value="${origValue}"]`) !== null;
            if(hasValue) {
                transferToMember.value = origValue;
            }
        }
    }

    /* asr实时对话文本框的功能 */
    _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_started, function (msg) {
        $(chatMessages).html("");
    });
    _phoneBar.on(ccPhoneBarSocket.eventList.asr_result_generate, function (msg) {
        handleAsrMessage(msg);
    });
    _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_end_customer, function (msg) {
        handleAsrMessage(msg);
    });
    _phoneBar.on(ccPhoneBarSocket.eventList.asr_process_end_agent, function (msg) {
        handleAsrMessage(msg);
    });
    const chatMessages = document.getElementById('chat-messages');
    $("#chat-container").hide();
    function handleAsrMessage(data) {
        $("#chat-container").show();
        const { status, object } = data;
        if (status === 619 && object) {
            const { role, text, vadType } = object;
            if(vadType == 1) {
                addMessageToChat(role, text);
            }
        } else if (status === 620 || status === 621) {
            addSystemMessage("对话已结束。");
        }
    }
    function addMessageToChat(role, text) {
        const messageDiv = document.createElement('div');
        messageDiv.className = 'message ' + (role === 1 ? 'customer' : 'agent');

        // 添加角色名称
        const roleHeader = document.createElement('div');
        roleHeader.className = 'message-header';
        roleHeader.textContent = role === 1 ? '客户' : '我';

        const messageContent = document.createElement('div');
        messageContent.textContent = text;

        // messageDiv.appendChild(roleHeader);
        messageDiv.appendChild(messageContent);
        chatMessages.appendChild(messageDiv);
        scrollToBottom();
    }
    function addSystemMessage(text) {
        const systemMessage = document.createElement('div');
        systemMessage.className = 'system-message';
        systemMessage.textContent = text;
        chatMessages.appendChild(systemMessage);
        scrollToBottom();
    }
    function scrollToBottom() {
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }

</script>

</body>
</html>